#!/usr/bin/env python

import pygame
from numpy import *
import pygame.draw
import pygame.key
import math
import os
import struct, socket, threading, sys


WHITE = 255, 255, 255
GREEN = 0, 255, 0
BLACK = 0, 0, 0
BLUE = 0, 0, 255
RED = 255, 0, 0
CUBE = 10
JMP = 15
SCREEN_SIZE = (320, 480)
PLAYER_SIZE = (CUBE, CUBE)
MOVE = CUBE

sLock = None
pLock = None
sock = None
gpsLoc = None
running = None
sendingGPS = None
widthRatio = 0
heightRatio = 0
players = []

class Player:
	def __init__(self, color=(0, 0, 0)):
		self.x = 0
		self.y = 0
		self.color = color
		self.trail = []
		self.area = []

	def getPos(self):
		return (self.x, self.y)
		
	def changeLoc(self, (x,y)):
		self.x = x
		self.y = y
		
	def resetPlayer(self):
		self.x = 0
		self.y = 0
		self.trail = []
		self.area = []
		
	def resetPlayer(self, (x,y)):
		self.x = x
		self.y = y
		self.trail = []
		self.area = []
        

def draw(screen):
	global pLock, players
	screen.fill(BLACK)
	pLock.acquire()
	for p in players:
		for x, y in p.trail:
			pygame.draw.rect(screen, (p.color[0] / 2, p.color[1] / 2, p.color[2] / 2) , (int(x * widthRatio), int(y * heightRatio)) + PLAYER_SIZE, 0)
		for x, y in p.area:
			pygame.draw.rect(screen, (p.color[0] / 1.5, p.color[1] / 1.5, p.color[2] / 1.5) , (int(x * widthRatio), int(y * heightRatio)) + (CUBE,CUBE), 0)
	for p in players:
		pygame.draw.rect(screen, p.color, (int(p.x*widthRatio),int(p.y*heightRatio)) + PLAYER_SIZE, 0)
	pLock.release()
	
	

def listener():
	global sock,players,sLock, pLock, running,sendingGPS,widthRatio,heightRatio
	#sLock.acquire()
	pLock.acquire()
	try:
		sock.settimeout(0.001)
		data = sock.recv(1)
		sock.settimeout(None)
		while len(data)<1:
			data += sock.recv(1-len(data))
		msgType,  = struct.unpack("!b",data)
		#print "msgType: "+str(int(msgType))
		if msgType == 0:
			pass
			#sLock.release()
		elif msgType == 1:
			data = sock.recv(12)
			while len(data)<12:
				data += sock.recv(12-len(data))
			p, x, y  = struct.unpack("!iii",data)
			players[p-1].trail.append((x, y))
			#sLock.release()
		elif msgType == 2:
			data = sock.recv(4)
			while len(data)<4:
				data += sock.recv(4-len(data))
			p, = struct.unpack("!i",data)
			players[p-1].trail = []
			#sLock.release()
		elif msgType == 3:
			data = sock.recv(12)
			while len(data)<12:
				data += sock.recv(12-len(data))
			p, x, y  = struct.unpack("!iii",data)
			players[p-1].area.append((x, y))
			#sLock.release()
		elif msgType == 4:
			data = sock.recv(12)
			while len(data)<12:
				data += sock.recv(12-len(data))
			p, x, y  = struct.unpack("!iii",data)
			#print "Moving Player: "+ str((p,x,y))
			players[p-1].changeLoc((x,y))
			#sLock.release()
		elif msgType == 5:
			#print "Starting to send GPS"
			data = sock.recv(8)
			while len(data)<8:
				data += sock.recv(8-len(data))
			arrWidth, arrHeight = struct.unpack("!ii",data)
			widthRatio = float(SCREEN_SIZE[0]) / float(arrWidth)
			heightRatio = float(SCREEN_SIZE[1]) / float(arrHeight)
			#print "W: " + str(widthRatio)
			#print "H: " + str(heightRatio)
			sendingGPS = True
			#sLock.release()
		else:
			pass
			#sLock.release()
	except socket.timeout:
		pass
	finally:
		sock.settimeout(None)
	pLock.release()
    
def main():
	global sock, running, players, gpsLoc, clientsLock, sendingGPS, sLock ,pLock
	startingLocLat = int(input("Enter Starting Location Latitude:"))
	startingLocLon = int(input("Enter Starting Location Longitude:"))
	gpsLoc = [startingLocLat, startingLocLon]
	players.append(Player(GREEN))
	players.append(Player(RED))
	players.append(Player(BLUE))
	running = True
	sendingGPS = False
	#sLock = threading.Semaphore()
	pLock = threading.Semaphore()
	sock = socket.socket(socket.AF_INET)
	sock.connect((sys.argv[1],int(sys.argv[2])))
	pygame.init()
	pygame.key.set_repeat(30, 30)
	os.environ['SDL_VIDEO_WINDOW_POS'] = '150,150'
	screen = pygame.display.set_mode(SCREEN_SIZE)
	msg = struct.pack('!c', 'C')
	#sLock.acquire()
	sock.sendall(msg)
	#sLock.release()
	#listenerThread = threading.Thread(None, listener)
	#listenerThread.start()
	#listenerThread.run()
	print "Sent \'C\'"
	draw(screen)
	pygame.display.flip()
	try:
		while running:
			listener()
			for event in pygame.event.get():
				#pygame.event.pump
				if event.type == pygame.QUIT:
					break
				if sendingGPS:
					key = pygame.key.get_pressed()  #checking pressed keys
					msg = None
					if key[pygame.K_a]:
						gpsLoc[1]-=JMP
						msg = struct.pack('!ii', gpsLoc[0], gpsLoc[1])
					if key[pygame.K_d]: 
						gpsLoc[1]+=JMP
						msg = struct.pack('!ii', gpsLoc[0], gpsLoc[1])
					if key[pygame.K_w]:
						gpsLoc[0]+=JMP
						msg = struct.pack('!ii', gpsLoc[0], gpsLoc[1])
					if key[pygame.K_s]:
						gpsLoc[0]-=JMP
						msg = struct.pack('!ii', gpsLoc[0], gpsLoc[1])
					if key[pygame.K_p]:
						print "0:\n\t"+str((players[0].x,players[0].y))+"\n\tColor:"+str(players[0].color)
						print "1:\n\t"+str((players[1].x,players[1].y))+"\n\tColor:"+str(players[1].color)
					if key[pygame.K_q]: 
						running = False
					#sLock.acquire()
					if msg!=None:
						sock.sendall(msg)
					#sLock.release()
			draw(screen)
			pygame.display.flip()
			#pygame.time.delay(500)
	finally:
		pygame.quit()
		sock.close()

if __name__ == '__main__':
    main()

